Istio安裝及使用

前言

k8s還沒摸很熟,新的東西就過來了。
這次是server mesh架構...

正文

前個工作還沒結束,新的東西就來了。
這次搞Istio,當然可以在東西都建立完後,再開始玩。
但這樣就會變成要把舊的pod砍掉重新建立了。

Istio 知識圖譜

image
ref.Istio Knowledge Map

安裝前

有查到要安裝istio 有最低的資源限制,但沒看到有明確的指定。
目前測試GKE的機器 設成 cpu 1 ram 2G 會發生 timeout的錯誤,
改成 cpu 2,ram 4G 則無此狀況。

7.fig-4.jpg

ref. istioctl install fails with multiple timeouts

機器大小設定

主要的節點區域,cpu則會吃到 900 mCPU,記憶體 2.75G
還沒安裝 kiali,jaeger,prometheus...等,
開機器大小時,需特別注意。

開始安裝

這次要安裝在GKE上,此次安裝的配置是 minimal版,
各版本的差異,不要看中文的,沒有更新。如果要看原理可以看。
請參考 Installation Configuration Profiles

 curl -L https://istio.io/downloadIstio | sh -
 cd istio-1.8.1
 export PATH=$PWD/bin:$PATH
 istioctl install

移除安裝

1.20指令更改為 istioctl uninstall -y --purge

istioctl x uninstall --purge
(注意 purge會把共用的東西通通刪光光,不使用purge也可刪除,但會留下 deployment以及 service)
istioctl x uninstall -f /Users/ezio_liu/Documents/k8s/Sample-Yaml/istio-sample-newingeressway.yaml (當初安裝的yaml)

ref. Getting Started
Uninstall Istio

安裝套件

在原目錄下執行

kubectl apply -f samples/addons
第一次執行完可能會有錯誤,可以在執行一次。
因執行建置的機器,會有時間差。
ref. Telemetry Addons

在namespace上面 植入 istio

kubectl label namespaces auto istio-injection=enabled

本來想使用自動植入,就是連這行也不用打。
但是 有些 k8s版本,本身會禁止這個行為,需要的話要另行打開。
ref. Automatic sidecar injection

此時可建立一個pod ,就可看到裡面多了一個 container

7. fig-1.jpg

如果植入sidecar失敗,出現
Internal error occurred: failed calling webhook "sidecar-injector.istio.io": Post https://istiod.istio-system.svc:443/inject?timeout=30s: context deadline exceeded

7.fig-5.jpg
需開啟GKE的master防火牆規則,增加 tcp:15017 的 port
(題外話,如果要使用kiali的話,請開啟 tcp: 8080 的 port,不然你會看kiali一直在轉圈圈)

7.fig-6.jpg

不知道要設定哪個防火牆規則,可下指令尋找

gcloud compute firewall-rules list --filter="name~gke-${CLUSTER_NAME}-[0-9a-z]*-master"

其中的 ${CLUSTER_NAME} 需改為你要尋找的叢集名稱

gcloud compute firewall-rules update <firewall-rule-name> --allow tcp:10250,tcp:443,tcp:15017,tcp:8080

ref.Google Kubernetes Engine

開啟套件

我是使用GKE,原本以為要能夠連到內部的服務,都要走外部ip
今天在亂點的時候,點到了這個地方,將那行指令複製,在本機執行。
前提是你的gcloud要有認證。

7. fig-2.jpg

他就能夠透過通訊埠轉發的方式存取。

7. fig-3.jpg
由(fig.3) 可以看到,他將本機的8080對到了service內的20001,
所以直接開啟網頁指向 localhost:8080 就可以看到該網頁的內容了。

佈署時由上往下開始佈署

DestinationRule

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: localgo
  namespace: auto
spec:
  host: localgo
  trafficPolicy:
    loadBalancer:
      simple: LEAST_CONN
  subsets:
    - name: Localgov1
      labels:
        version: v1
    - name: v2
      labels:
        version: v2

ref. Destination Rule

參數說明
trafficPolicy內的 loadBalancer:
代表的是幾種流量分發方式:
•Round_Robin: 輪詢演算法,顧名思義請求將會依次發給每一個例項,來共同分擔所有的請求。

•Random: 隨機演算法,將所有的請求隨機分發給健康的例項

•Least_Conn: 最小連線數,在所有健康的例項中任選兩個,將請求發給連線數較小的那一個例項。

ref. idou老師教你學Istio 19 : Istio 流量治理功能原理與實戰

VirtualService

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: localgo-vs
  namespace: auto
spec:
  hosts:
  - "*"
  gateways:
    - istio-ingressgateway
  http:
  - name: "route-v1"
    route:
    - destination:
        port:
          number: 80
        host: localgo.auto.svc.cluster.local    #這裡就是指向你真正服務 service 的名稱喔
        subset: Localgov1   #這裡指的是DestinationRule的subset.name
      weight: 80
    - destination:
        port:
          number: 80
        host: localgo.auto.svc.cluster.local
        # 上面 destionation 下面的 host 名稱會這麼長,這是 k8s 內部實際 dns 全名,如果需要跨 namspace 存取,就需要用這樣的全名方式指定。
        # {service name}.{namespace}.svc.cluster.local 這就是它的規則
        subset: v2
      weight: 20
      corsPolicy:  ##限制
        allowOrigin:    #允許所有來源
          - '*'

corsPolicy 有以下的選項

weight 則是用來做流量分配用的
同一個route內,相加必須 =100

詳細說明,參考下面連結
ref.
CorsPolicy細項設定

然後在 這邊還有另一種是 match的用法,
虛擬服務中定義的第一條規則有最高優先級,
當第一個沒有match到相對應的規則時,
則繼續往下執行。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: localgo-vs
  namespace: auto
spec:
  hosts:
  - "*"
  gateways:
    - istio-ingressgateway
  http:
  - name: "route-v1"
    match:
    - uri:
        prefix: /reviews
    route:
    - destination:
        port:
          number: 80
        host: localgo.auto.svc.cluster.local    #這裡就是指向你真正服務 service 的名稱喔
        subset: Localgov1   #這裡指的是DestinationRule的subset.name
  - name: "route-v3"
    match:
      - uri:
          prefix: /Player
    route:
     - destination:
        port:
          number: 80
        host: localgo.auto.svc.cluster.local    #這裡就是指向你真正服務 service 的名稱喔
        subset: Localgov1   #這裡指的是DestinationRule的subset.name       
  - name: "route-v2"
    route:
    - destination:
        port:
          number: 80
        host: localgo.auto.svc.cluster.local
        # 上面 destionation 下面的 host 名稱會這麼長,這是 k8s 內部實際 dns 全名,如果需要跨 namspace 存取,就需要用這樣的全名方式指定。
        # {service name}.{namespace}.svc.cluster.local 這就是它的規則
        subset: v2

match 下面的用法

上面那段的規則為,當網址進來後,如果網域的後面不是reviews的話,
則往下執行到route-v3,如果網址為 Player的話,則執行下面的路由
ref.
StringMatch
路由規則
Day24 什麼是 istio virtual service?

gateway

apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
  name: istio-ingressgateway
  # 這裡就是填入kubectl get service -n istio-system 所查到的 istio-ingressgateway,實務上如果你有多個 ip ,就會有多個 gateway 代理,
  # 然後就要描述多個 gateway 去使用 gateway 代理
  namespace: auto
spec:
  selector:
    istio: ingressgateway   # 使用默認的控制器
  servers:
  - port: #加密傳輸
      number: 443
      name: https
      protocol: HTTPS
    tls:
      mode: SIMPLE
      serverCertificate: /etc/istio/ingressgateway-certs/tls.crt #設定憑證路徑
      privateKey: /etc/istio/ingressgateway-certs/tls.key  #設定憑證路徑
    hosts:
     - "*" #該服務對應domain
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
     - "*" #該服務對應domain

ref. istio gateway 是什麼?

同一個叢集安裝多個ingressgateway

滿滿的坑,卡了兩天才搞定。

這邊要改使用operator安裝
所以先初始化

istioctl operator init

ref. Istio Operator Install

再來設定新增的 ingressgateway

kind: IstioOperator
apiVersion: install.istio.io/v1alpha1
metadata:
  annotations:
    install.istio.io/ignoreReconcile: 'true'
  name: video-state
  namespace: istio-system
spec:
  addonComponents:
    istiocoredns:
      enabled: false
  components:
    base:
      enabled: true
    cni:
      enabled: false
    ingressGateways:
        - name: ingressgateway-private
          namespace: istio-system
          enabled: true
          k8s:
              env:
                - name: ISTIO_META_ROUTER_MODE
                  value: standard          
              hpaSpec:
                minReplicas: 2
              overlays:
                    - kind: HorizontalPodAutoscaler
                      name: ingressgateway-private
                      patches:
                        - path: metadata.labels.app
                          value: ingressgateway-private
                        - path: metadata.labels.istio
                          value: ingressgateway-private
                        - path: spec.scaleTargetRef.name
                          value: ingressgateway-private
                    - kind: Deployment
                      name: ingressgateway-private
                      patches:
                        - path: metadata.labels.app
                          value: ingressgateway-private
                        - path: metadata.labels.istio
                          value: ingressgateway-private
                        - path: spec.selector.matchLabels.app
                          value: ingressgateway-private
                        - path: spec.selector.matchLabels.istio
                          value: ingressgateway-private
                        - path: spec.template.metadata.labels.app
                          value: ingressgateway-private
                        - path: spec.template.metadata.labels.istio
                          value: ingressgateway-private
                    - kind: Service
                      name: ingressgateway-private
                      patches:
                        - path: metadata.labels.app
                          value: ingressgateway-private
                        - path: metadata.labels.istio
                          value: ingressgateway-private
                        - path: spec.selector.app
                          value: ingressgateway-private
                        - path: spec.selector.istio
                          value: ingressgateway-private
                    - kind: PodDisruptionBudget
                      name: ingressgateway-private
                      patches:
                        - path: metadata.name
                          value: ingressgateway-private
                        - path: metadata.labels.app
                          value: ingressgateway-private
                        - path: metadata.labels.istio
                          value: ingressgateway-private
                        - path: spec.selector.matchLabels.app
                          value: ingressgateway-private
                        - path: spec.selector.matchLabels.istio
                          value: ingressgateway-private

先使用
istioctl manifest generate -f newingeressway.yaml
預先編譯一下,看有沒有成功。 istioctl manifest的原理,有點像是kustomize,
有一個基底,後面的程式都是根據這個基底去修改覆蓋。

安裝的話,則是使用
istioctl manifest install -f newingeressway.yaml

ref.
Multiple ingress controller services via IstioOperator?
istio
Istio入門與實戰